home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
SESANIM.ZIP
/
!SESanim
/
Sources
/
c
/
savesprite
< prev
next >
Wrap
Text File
|
1997-05-11
|
5KB
|
215 lines
/* SaveSprite.c */
/* Saving an anim as a RiscOS sprite file
* (K) All Rites Reversed - Copy What You Like (see file Copying)
*
* Authors:
* Peter Hartley <peter@ant.co.uk>
*
* History:
* 23-Oct-96 pdh Started
* 27-Oct-96 pdh Frob to cope with 3/5/6/7bpp anim's
* 27-Oct-96 *** Release 4beta1
* 29-Oct-96 pdh Fix mask code so it expands to whole pixels properly
* 29-Oct-96 *** Release 4beta2
* 07-Nov-96 *** Release 4
* 15-Dec-96 *** Release 5beta1
* 01-Jan-97 pdh Fix bug in saving 2bpp sprites
* 27-Jan-97 *** Release 5beta2
* 29-Jan-97 *** Release 5beta3
* 03-Feb-97 *** Release 5
* 07-Feb-97 *** Release 5.01
*
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "DeskLib:Sprite.h"
#include "bitmap.h"
#include "count.h"
#include "utils.h"
#if 0
#define debugf printf
#define DEBUG 1
#else
#define debugf 1?0:printf
#define DEBUG 0
#endif
void CompressSpriteLine( char *dest, char *src, int n, int bpp )
{
int i;
switch ( bpp )
{
case 8:
memcpy( dest, src, n );
break;
case 4:
for ( i=0; i< (n+1)/2; i++ )
dest[i] = src[i<<1] + ( src[(i<<1)+1] << 4 );
break;
case 2:
memset( dest, 0, (n+3)/4 );
for ( i=0; i<n; i++ )
dest[i>>2] |= (src[i]) << ((i&3)*2);
break;
case 1:
memset( dest, 0, (n+7)/8 );
for ( i=0; i<n; i++ )
dest[i>>3] |= (src[i]) << (i&7);
break;
}
}
void CompressMaskLine( char *dest, char *src, int n, int bpp )
{
int i;
switch ( bpp )
{
case 8:
for ( i=0; i<n; i++ )
dest[i] = ( src[i] ) ? 0xFF : 0;
break;
case 4:
for ( i=0; i< (n+1)/2; i++ )
dest[i] = ( src[i<<1] ? 0xF : 0 )
+ ( ( src[(i<<1)+1] ? 0xF : 0 ) << 4 );
break;
case 2:
memset( dest, 0, (n+3)/4 );
for ( i=0; i<n; i++ )
dest[i>>2] |= ( src[i] ? 3 : 0 ) << ((i&3)*2);
break;
case 1:
memset( dest, 0, (n+7)/8 );
for ( i=0; i<n; i++ )
dest[i>>3] |= (src[i]) << (i&7);
break;
}
}
/* Sprites are only available in 1, 2, 4, 8 bpp */
const char bppmap[8] = { 1, 2, 4, 4, 8, 8, 8, 8 };
BOOL Anim_MakeSprite( anim a, FILE *output )
{
sprite_areainfo sai;
sprite_header *psh;
int nSpriteSize;
int i,y;
int newbpp;
int abw;
void *data;
/* unsigned int palette[256];*/
int newncol;
frameptr f2 = Anim_OpenFrame( a, 0 );
int nFrames = a->nFrames;
if ( !f2 )
{
/* There was an error */
return FALSE;
}
newbpp = bppmap[ MinBpp( f2->nColours ) - 1 ];
newncol = 1 << newbpp;
abw = ( ( (a->nWidth*newbpp)+31 ) >> 3 ) & ~3; /* aligned byte width */
nSpriteSize = abw;
nSpriteSize *= a->nHeight;
nSpriteSize *= 2;
nSpriteSize += 8*newncol;
nSpriteSize += sizeof( sprite_header );
Anim_CloseFrame( a, &f2 );
/* Write the header */
sai.numsprites = nFrames;
sai.firstoffset = 16;
sai.freeoffset = 16 + nFrames*nSpriteSize;
fwrite( &sai.numsprites, 1, 12, output );
data = Anim_Allocate( nSpriteSize );
if ( !data )
{
Anim_NoMemory( "savesprite" );
return FALSE;
}
psh = (sprite_header*) data;
/* Write the frames */
psh->offset_next = nSpriteSize;
psh->width = (abw>>2)-1;
psh->height = a->nHeight-1;
psh->leftbit = 0;
psh->rightbit = (a->nWidth*newbpp - 1 ) & 31;
psh->imageoffset = sizeof(sprite_header) + 8*newncol;
psh->maskoffset = psh->imageoffset + abw*a->nHeight;
switch ( newbpp )
{
case 1: psh->screenmode = 18; break;
case 2: psh->screenmode = 19; break;
case 4: psh->screenmode = 20; break;
case 8: psh->screenmode = 21; break;
}
for ( i=0; i < a->nFrames; i++ )
{
frameptr f = Anim_OpenFrame( a, i );
char *src;
char *dest;
unsigned int *pPal = (unsigned int*)(psh+1);
int delay;
if ( !f )
{
Anim_Free( &data );
return FALSE;
}
src = f->pImage;
memset( psh->name, 0, 12 );
delay = Anim_GetDelay( a, i, -1 );
if ( delay != -1 )
sprintf( psh->name, "%03ddelay%d", i, delay );
else
sprintf( psh->name, "%03d", i );
for ( y=0; y < f->nColours; y++ ) /* NOT newncol */
{
*pPal++ = f->pPalette[y];
*pPal++ = f->pPalette[y];
}
src = f->pImage;
dest = ((char*)(psh+1)) + newncol*8;
for ( y=0; y < a->nHeight; y++ )
{
CompressSpriteLine( dest, src, a->nWidth, newbpp );
dest += abw;
src += a->nWidth;
}
src = f->pMask;
for ( y=0; y < a->nHeight; y++ )
{
CompressMaskLine( dest, src, a->nWidth, newbpp );
dest += abw;
src += a->nWidth;
}
Anim_CloseFrame( a, &f );
fwrite( data, 1, nSpriteSize, output );
}
Anim_Free( &data );
return TRUE;
}